在現代 Web 應用開發中,表單的管理與驗證往往是開發過程中的一大挑戰。上一篇文章中,我們探討了如何追蹤使用者行為並優化應用體驗,而今天,我們的焦點是表單管理。具體來說,我們將深入學習如何使用 react-hook-form
來高效處理 "Let’s Collaborate" 表單,並深入探討它背後的原理與最佳實踐。
react-hook-form
在大型應用程式中,表單管理往往是一項重複且容易出錯的工作。React 的受控組件(controlled components)在處理複雜表單時,經常會導致性能問題,例如頻繁重渲染或狀態管理困難。這時,react-hook-form
提供了以下的優勢:
react-hook-form
提供的 API 如 useForm()
和 register()
,讓開發者可以快速管理表單並實現自定義邏輯。接下來,我們將以 "Let’s Collaborate" 表單為例,展示如何將 react-hook-form
集成到項目中,並結合表單驗證及性能優化進行實作。
react-hook-form
首先,我們需要安裝 React-Hook-Form:
npm install react-hook-form
安裝 react-hook-form
是實現高效表單管理的第一步,它提供了基本的表單處理功能,後續的驗證和數據處理邏輯都將基於這個庫。
以下是基於 react-hook-form
實現的表單組件代碼,我們將探討其內部機制及設計選擇:
import React from 'react';
import { useForm } from 'react-hook-form';
import * as styles from '@/components/Form/ContactForm.module.scss';
const ContactForm = () => {
// 使用 useForm hook 來管理表單
const { register, handleSubmit, formState: { errors } } = useForm();
// 表單提交處理
const onSubmit = (data) => {
console.log('Form submitted:', data);
// 這裡可以加入 API 提交邏輯
};
return (
<form className={styles.contactForm} onSubmit={handleSubmit(onSubmit)}>
<div className={styles.formGroup}>
<label htmlFor="name">Name</label>
<input
type="text"
{...register('name', { required: 'Name is required' })}
placeholder="Your Name"
/>
{errors.name && <p className={styles.errorText}>{errors.name.message}</p>}
</div>
<div className={styles.formGroup}>
<label htmlFor="email">Email</label>
<input
type="email"
{...register('email', {
required: 'Email is required',
pattern: {
value: /\S+@\S+\.\S+/,
message: 'Enter a valid email',
},
})}
placeholder="Your Email"
/>
{errors.email && <p className={styles.errorText}>{errors.email.message}</p>}
</div>
<div className={styles.formGroup}>
<label htmlFor="serviceItem">Service Items</label>
<select
{...register('serviceItem', { required: 'Please select a service item' })}
>
<option value="">Select a service</option>
<option value="design">Design</option>
<option value="development">Development</option>
<option value="consultation">Consultation</option>
</select>
{errors.serviceItem && <p className={styles.errorText}>{errors.serviceItem.message}</p>}
</div>
<div className={styles.formGroup}>
<label htmlFor="projectDetails">Project Details</label>
<textarea
{...register('projectDetails', { required: 'Project details are required' })}
placeholder="Describe your project"
></textarea>
{errors.projectDetails && <p className={styles.errorText}>{errors.projectDetails.message}</p>}
</div>
<button type="submit" className={styles.submitButton}>
Submit
<img src={require(`@/assets/icons/Submit.svg`)} alt="Submit" className={styles.submitIcon} />
</button>
</form>
);
};
export default ContactForm;
說明:
useForm
:useForm()
是 react-hook-form
的核心 Hook。它提供了對表單數據的全面控制,並簡化了表單輸入、驗證及提交邏輯。這裡我們從 useForm
中提取了 register
、handleSubmit
和 errors
,這三個函數和對象是管理表單邏輯的關鍵。register
用於註冊輸入框:我們通過 register
函數將表單元素(如 input
和 textarea
)與表單管理系統連接。這樣 react-hook-form
就可以跟蹤這些元素的狀態並進行驗證。required
、pattern
等。這樣當用戶提交表單時,react-hook-form
會自動檢查這些條件是否滿足,如果不滿足,則在 errors
對象中記錄相應的錯誤資訊。react-hook-form
是基於非受控組件的,React 的狀態不會在每次輸入變動時被更新。相比於使用 useState
管理表單輸入,這種方式顯著減少了重渲染次數,提高了應用的響應速度。這部分展示了如何在網頁上整合聯絡資訊(如營業時間、聯絡方式)與嵌入的表單,並使用 i18n
進行多語言處理。這樣可以實現根據使用者語言動態顯示不同語言的內容,提升國際化的支持。
import React from 'react';
import { useTranslation } from 'react-i18next';
import * as styles from './ContactSection.module.scss';
import ContactForm from '@/components/Form/ContactForm';
const ContactSection = ({ id }) => {
const { t } = useTranslation(); // 引入翻譯函數
return (
<div id={id} className={styles.subcontainer}>
<div className={styles.infoSection}>
<h2 className={styles.title}>{t('collaborate.title')}</h2>
<p className={styles.description}>
{t('collaborate.description')}
</p>
<div className={styles.infoBox}>
<div className={styles.infoItem}>
<img src={require(`@/assets/icons/Open.svg`)} alt="Open" className={styles.icon} />
<div>
<div className={styles.infoTitle}>{t('collaborate.businessHours')}</div>
<div className={styles.description}>{t('collaborate.hours')}</div>
</div>
</div>
<div className={styles.infoItem}>
<img src={require(`@/assets/icons/Newsletter.svg`)} alt="Email" className={styles.icon} />
<div>
<div className={styles.infoTitle}>{t('collaborate.email')}</div>
<div className={styles.description}>carol.cheng@luma-c.com</div>
</div>
</div>
<div className={styles.infoItem}>
<img src={require(`@/assets/icons/LINE.svg`)} alt="Chat" className={styles.icon} />
<div>
<div className={styles.infoTitle}>{t('collaborate.lineId')}</div>
<div className={styles.description}>@430trfzv</div>
</div>
</div>
</div>
</div>
<ContactForm /> {/* 嵌入表單組件 */}
</div>
);
}
export default ContactSection;
這裡,我們展示了聯絡資訊(如營業時間、聯絡信箱和 LINE ID),並以多語言格式呈現,用戶根據不同語言環境能看到本地化的聯絡資訊描述。
現在表單具備了基本的驗證功能,你可以進行以下幾項測試來確保表單正常運作:
abc@
)時,表單應該提示 Email 格式錯誤。react-hook-form
不僅為我們提供了一個輕量級、高效能的表單管理方案,還通過簡潔的 API 幫助我們輕鬆應對複雜表單的驗證與狀態管理。從基本的輸入驗證到異步驗證,甚至是多步驟表單,react-hook-form
皆能靈活應對。
如果你正在尋找一個能顯著提升表單效能的工具,不妨試試 react-hook-form
。在下一篇文章中,我們將進一步探討如何將表單數據提交到後端 API,並處理表單提交的狀態與回應。
✨ 流光館Luma<∕> ✨ 期待與你繼續探索更多技術知識!